//
//  CacheData+SeparateDown.m
//  KidReading
//
//  Created by linziyuan on 16/12/27.
//  Copyright © 2016年 刘赞黄Telen. All rights reserved.
//

#import "CacheData+SeparateDown.h"
#import "ConstDefine.h"

@implementation CacheData (SeparateDown)


#pragma mark SeprateDown
/*
 //cache信息
 
 key: {
 paths:{urlhash:edtion, urlhash:edtion,...};
 beforePahts:{urlhash:edtion}, urlhash:edtion,...},
 afterPaths:{urlhash:edtion}, {urlhash:edtion,...},
 }
 
 */

//返回当前书需要下载的infolist
- (NSArray *)isBookNeedDown:(NSInteger)bookId currentInfoList:(NSDictionary *)infoList{
    NSMutableArray *needDownArr = nil;
    NSDictionary *cacheinfo = [self getCacheInfoForBook:bookId currentInfoList:infoList key:[NSString stringWithFormat:@"%@",@(bookId)]];
    //同时更新bookDowning数据
    NSString* downingKey = [NSString stringWithFormat:@"%@_%@",@(bookId),__BookDownIng];
    [self getCacheInfoForBook:bookId currentInfoList:infoList key:downingKey];
    if (cacheinfo && infoList) {
        needDownArr = [NSMutableArray array];
        NSDictionary *cacheParts = [cacheinfo valueForKey:TBKey_Parts];
        NSArray *originParts = [infoList valueForKey:TBKey_Parts];
        [self opearationNewInfoArr:originParts cacheDict:cacheParts containner:needDownArr];
        
        NSDictionary *cacheBefore = [cacheinfo valueForKey:TBKey_BeforeParts];
        NSArray *originBeforeParts = [infoList valueForKey:TBKey_BeforeParts];
        [self opearationNewInfoArr:originBeforeParts cacheDict:cacheBefore containner:needDownArr];
        
        NSDictionary *cacheAfter = [cacheinfo valueForKey:TBKey_AfterParts];
        NSArray *originAfterParts = [infoList valueForKey:TBKey_AfterParts];
        [self opearationNewInfoArr:originAfterParts cacheDict:cacheAfter containner:needDownArr];
    }
    return needDownArr;
}

- (NSArray *)isBookNeedDown:(NSInteger)bookId currentInfoList:(NSDictionary *)infoList forUid:(NSInteger)uid {
    NSMutableArray *needDownArr = nil;
    NSString* key = [NSString stringWithFormat:@"%@",@(bookId)];
    NSString* kys = [NSString stringWithFormat:@"%@__%@",@(uid),key];
    NSDictionary *cacheinfo = [self getCacheInfoForBook:bookId currentInfoList:infoList key:kys];
    if (cacheinfo && infoList) {
        needDownArr = [NSMutableArray array];
        NSDictionary *cacheParts = [cacheinfo valueForKey:TBKey_Parts];
        NSArray *originParts = [infoList valueForKey:TBKey_Parts];
        [self opearationNewInfoArr:originParts cacheDict:cacheParts containner:needDownArr];
        
        NSDictionary *cacheBefore = [cacheinfo valueForKey:TBKey_BeforeParts];
        NSArray *originBeforeParts = [infoList valueForKey:TBKey_BeforeParts];
        [self opearationNewInfoArr:originBeforeParts cacheDict:cacheBefore containner:needDownArr];
        
        NSDictionary *cacheAfter = [cacheinfo valueForKey:TBKey_AfterParts];
        NSArray *originAfterParts = [infoList valueForKey:TBKey_AfterParts];
        [self opearationNewInfoArr:originAfterParts cacheDict:cacheAfter containner:needDownArr];
    }
    return needDownArr;
}

- (void)opearationNewInfoArr:(NSArray *)originArr cacheDict:(NSDictionary *)cahceDict containner:(NSMutableArray *)needDownArr {
    NSArray *allkeys = cahceDict.allKeys;
    @autoreleasepool {
        for (NSDictionary *oriItem in originArr) {
            NSString *url = [oriItem valueForKey:@"uri"];
            NSString *hasUrl = [NSString stringWithFormat:@"%lld",(unsigned long long)[url hash]];
            long long originEdtion = [[oriItem valueForKey:@"edition"] longLongValue];
#if __Debug_File
            NSLog(@"-originEdtion:--%lld",originEdtion);
#endif
            if ([allkeys containsObject:hasUrl]) {
                long long cacheEdtion = [[cahceDict valueForKey:hasUrl] longLongValue];
#if __Debug_File
                NSLog(@"-cacheEdtion:--%lld",cacheEdtion);
#endif
                if (originEdtion > cacheEdtion) {
                    [needDownArr addObject:oriItem];
                }
            }else {
                [needDownArr addObject:oriItem];
            }
        }
    }
}



//- (NSDictionary *)getCacheInfoForBook:(NSInteger)bookid currentInfoList:(NSDictionary *)infoList isUpdate:(void (^)(BOOL))isupdate {
//    return [self getCacheInfoForBook:bookid currentInfoList:infoList key:[NSString stringWithFormat:@"%@",@(bookid)] isUpdate:isupdate];
//}



- (NSDictionary *)getCacheInfoForBook:(NSInteger)bookid currentInfoList:(NSDictionary *)infoList{
    return [self getCacheInfoForBook:bookid currentInfoList:infoList key:[NSString stringWithFormat:@"%@",@(bookid)] isUpdate:nil];
}

- (NSDictionary *)getCacheInfoForBook:(NSInteger)bookid currentInfoList:(NSDictionary *)infoList key:(NSString *)keystr {
    return [self getCacheInfoForBook:bookid currentInfoList:infoList key:keystr isUpdate:nil];
}

//获取缓存infoList [ 若原缓存为edtion(字符串)，转换为infolist格式 ]
- (NSDictionary *)getCacheInfoForBook:(NSInteger)bookid currentInfoList:(NSDictionary *)infoList key:(NSString *)keystr isUpdate:(void (^)(BOOL))isupdate{
    id cacheData = [bookCache objectForKey:keystr];
    if (cacheData) {
        if ([cacheData isKindOfClass:[NSDictionary class]]) {
            NSDictionary *cacheinfo = (NSDictionary *)cacheData;
            if (isupdate) {
                isupdate(NO);
            }
            return cacheinfo;
        }else { //原缓存是edtion的情况
            NSString *edtion = (NSString *)cacheData;
            NSMutableDictionary *mtotalInfoDict = [NSMutableDictionary dictionary];
            //parts
            NSArray *oriPartsArr = [infoList valueForKey:TBKey_Parts];
            [self replaceOldCacheWithEdtion:edtion curretnArr:oriPartsArr typeStr:TBKey_Parts containner:mtotalInfoDict];
            //beforeParts
            NSArray *oriBeforeArr = [infoList valueForKey:TBKey_BeforeParts];
            [self replaceOldCacheWithEdtion:@"1" curretnArr:oriBeforeArr typeStr:TBKey_BeforeParts containner:mtotalInfoDict];
            //afterParts
            NSArray *oriAfterArr = [infoList valueForKey:TBKey_AfterParts];
            [self replaceOldCacheWithEdtion:@"1" curretnArr:oriAfterArr typeStr:TBKey_AfterParts containner:mtotalInfoDict];
            [bookCache setValue:mtotalInfoDict forKey:keystr];
            [self saveBookCache];
            if (isupdate) {
                isupdate(YES);
            }
            return mtotalInfoDict;
        }
    }
    if (isupdate) {
        isupdate(NO);
    }
    return nil;
}

- (void)replaceOldCacheWithEdtion:(NSString *)oldEdtion curretnArr:(NSArray *)originArr typeStr:(NSString *)typeStr containner:(NSMutableDictionary *)container {
    NSMutableDictionary *mCdict = [NSMutableDictionary dictionary];
    @autoreleasepool {
        for (NSDictionary *infoItem in originArr) {
            NSString *url = [infoItem valueForKey:@"uri"];
            NSString *hasUrl = [NSString stringWithFormat:@"%lld",(unsigned long long)[url hash]];
            [mCdict setValue:oldEdtion forKey:hasUrl];
        }
    }
    [container setValue:mCdict forKey:typeStr];
}

//更新下载完成infolist
-(void)updateBook:(NSInteger)bookid CacheInfoData:(NSDictionary *)cacheInfo {
    NSString* key = [NSString stringWithFormat:@"%@",@(bookid)];
    [self updateCacheInfoListWithBookId:bookid key:key originInfoList:cacheInfo];
    NSMutableArray* marr = [[NSMutableArray alloc] initWithArray:[bookCache objectForKey:__BookDownOrderArr]];
    BOOL needAdd = YES;
    @autoreleasepool {
        for (NSString* ky in marr) {
            if(ky.length==0)continue;
            if ([key isEqual:ky]) {
                needAdd = NO;
                break;
            }
        }
    }
    if(needAdd)[marr addObject:key];
    [bookCache setObject:marr forKey:__BookDownOrderArr];
    [self saveBookCache];
}

//更新下载完成infolist forUid
-(void)updateBook:(NSInteger)bookid CacheInfoData:(NSDictionary *)cacheinfo forUid:(NSInteger)uid {
    NSString* key = [NSString stringWithFormat:@"%@",@(bookid)];
    NSString* kys = [NSString stringWithFormat:@"%@__%@",@(uid),key];
    [self updateCacheInfoListWithBookId:bookid key:kys originInfoList:cacheinfo];
    //
    NSString* ky_order = [NSString stringWithFormat:@"%d__%@",(int)uid,__BookDownOrderArr];
    NSMutableArray* marr = [[NSMutableArray alloc] initWithArray:[bookCache objectForKey:ky_order]];
    BOOL needAdd = YES;
    @autoreleasepool {
        for (NSString* ky in marr) {
            if(ky.length==0)continue;
            if ([key isEqual:ky]) {
                needAdd = NO;
                break;
            }
        }
    }
    if(needAdd)[marr addObject:key];
    [bookCache setObject:marr forKey:ky_order];
    [self saveBookCache];
}

- (void)deleteDowninginfoWithbookid:(NSInteger)bookid downList:(NSArray *)listArr {
    NSString* key = [NSString stringWithFormat:@"%@_%@",@(bookid),__BookDownIng];
    NSDictionary *downIngDict = [bookCache valueForKey:key];
    if (listArr.count && downIngDict) {
        NSMutableDictionary *mdict = [NSMutableDictionary dictionaryWithDictionary:downIngDict];
        @autoreleasepool {
            for (NSDictionary *listItem in listArr) {
                NSString *sortMark = [listItem valueForKey:TBKey_SortMark];
                NSDictionary *cacheDict = [mdict valueForKey:sortMark];
                NSMutableDictionary *mcacheDict = [NSMutableDictionary dictionaryWithDictionary:cacheDict];
                NSString *url = [listItem valueForKey:@"uri"];
                NSString *hasUrl = [NSString stringWithFormat:@"%lld",(unsigned long long)[url hash]];
                [mcacheDict removeObjectForKey:hasUrl];
                
                [mdict setValue:mcacheDict forKey:sortMark];
            }
        }
        [bookCache setValue:mdict forKey:key];
        [self saveBookCache];
    }
}
//更新下载中的infolist (单个patrs字典更新)
-(void)updateDowningBook:(NSInteger)bookid infoItem:(NSDictionary *)infoItem
{
    if (infoItem) {
        NSString* key = [NSString stringWithFormat:@"%@_%@",@(bookid),__BookDownIng];
        NSDictionary *downIngDict = [bookCache valueForKey:key];
        
        NSString *sortMark = [infoItem valueForKey:TBKey_SortMark];
        NSString *url = [infoItem valueForKey:@"uri"];
        NSString *hasUrl = [NSString stringWithFormat:@"%lld",(unsigned long long)[url hash]];
        NSString *edtion = [infoItem valueForKey:@"edition"];
        
        NSMutableDictionary *mdict = nil;
        if (downIngDict) {
            mdict = [NSMutableDictionary dictionaryWithDictionary:downIngDict];
            NSMutableArray *mitem = [mdict valueForKey:sortMark];
            [mitem setValue:edtion forKey:hasUrl];
        }else {
            mdict = [NSMutableDictionary dictionary];
            NSMutableDictionary *mItem = [NSMutableDictionary dictionary];
            [mItem setValue:edtion forKey:hasUrl];
            [mdict setValue:mItem forKey:sortMark];
            if ([sortMark isEqualToString:TBKey_Parts]) {
                [mdict setValue:[NSMutableDictionary dictionary] forKey:TBKey_BeforeParts];
                [mdict setValue:[NSMutableDictionary dictionary] forKey:TBKey_AfterParts];
            }else if ([sortMark isEqualToString:TBKey_BeforeParts]) {
                [mdict setValue:[NSMutableDictionary dictionary] forKey:TBKey_Parts];
                [mdict setValue:[NSMutableDictionary dictionary] forKey:TBKey_AfterParts];
            }else if ([sortMark isEqualToString:TBKey_AfterParts]) {
                [mdict setValue:[NSMutableDictionary dictionary] forKey:TBKey_Parts];
                [mdict setValue:[NSMutableDictionary dictionary] forKey:TBKey_BeforeParts];
            }
        }
        [bookCache setValue:mdict forKey:key];
#if __Debug_File
        NSLog(@"-book downing info --%@",mdict);
#endif
        [self saveBookCache];
    }
}

//获取url Edtion
- (long long)getEditionForDownIngBook:(NSInteger)bookid url:(NSString *)url
{
    if (url) {
        NSString *key = [NSString stringWithFormat:@"%@_%@",@(bookid).description,__BookDownIng];
        NSDictionary *listInfo = [bookCache valueForKey:key];
        NSString *hasUrl = [NSString stringWithFormat:@"%lld",(unsigned long long)[url hash]];
        return [self getEdtion:listInfo ForPath:hasUrl];
    }
    return 0;
}


- (void)updateCacheInfoListWithBookId:(NSInteger)bookid key:(NSString *)key originInfoList:(NSDictionary *)originList {
    NSDictionary *cacheListInfo = [self getCacheInfoForBook:bookid currentInfoList:originList key:key];//[bookCache valueForKey:key];
    NSMutableDictionary *mtotalDict = nil;
    if (cacheListInfo) {            //已经有缓存，更新
        mtotalDict = [NSMutableDictionary dictionaryWithDictionary:cacheListInfo];
        //parts
        NSArray *partsArr = [originList valueForKey:TBKey_Parts];
        if (partsArr.count ) {
            NSDictionary *cachePartDict = [cacheListInfo valueForKey:TBKey_Parts];
            NSMutableDictionary *mCachePartDict = [cachePartDict mutableCopy];
            for (NSDictionary *originItem in partsArr) {
                [self replaceWithOriginItem:originItem container:mCachePartDict];
            }
            [mtotalDict setValue:mCachePartDict forKey:TBKey_Parts];
        }
        //beforeParts
        NSArray *beforeArr = [originList valueForKey:TBKey_BeforeParts];
        if (beforeArr.count) {
            NSDictionary *cacheBeforeDict = [cacheListInfo valueForKey:TBKey_BeforeParts];
            NSMutableDictionary *mCacheBeforeDict = [cacheBeforeDict mutableCopy];
            for (NSDictionary *originItem in beforeArr) {
                [self replaceWithOriginItem:originItem container:mCacheBeforeDict];
            }
            [mtotalDict setValue:mCacheBeforeDict forKey:TBKey_BeforeParts];
        }
        //afterParts
        NSArray *afterArr = [originList valueForKey:TBKey_AfterParts];
        if (afterArr.count) {
            NSDictionary *cacheAfterDict = [cacheListInfo valueForKey:TBKey_AfterParts];
            NSMutableDictionary *mCacheAfterDict = [cacheAfterDict mutableCopy];
            for (NSDictionary *originItem in afterArr) {
                [self replaceWithOriginItem:originItem container:mCacheAfterDict];
            }
            [mtotalDict setValue:mCacheAfterDict forKey:TBKey_AfterParts];
        }
    }else {                     //没有缓存，新建
        mtotalDict = [NSMutableDictionary dictionary];
        //parts
        NSArray *partsArr = [originList valueForKey:TBKey_Parts];
        if (partsArr.count) {
            NSMutableDictionary *mPartsDict = [NSMutableDictionary dictionary];
            for (NSDictionary *infoItem in partsArr) {
                [self replaceWithOriginItem:infoItem container:mPartsDict];
            }
            [mtotalDict setValue:mPartsDict forKey:TBKey_Parts];
        }else {
            [mtotalDict setValue:[NSMutableDictionary dictionary] forKey:TBKey_Parts];
        }
        //beforeParts
        NSArray *beforeArr = [originList valueForKey:TBKey_BeforeParts];
        if (beforeArr.count) {
            NSMutableDictionary *mBeforeDict = [NSMutableDictionary dictionary];
            for (NSDictionary *infoItem in beforeArr) {
                [self replaceWithOriginItem:infoItem container:mBeforeDict];
            }
            [mtotalDict setValue:mBeforeDict forKey:TBKey_BeforeParts];
        }else {
            [mtotalDict setValue:[NSMutableDictionary dictionary] forKey:TBKey_BeforeParts];
        }
        //afterParts
        NSArray *afterArr = [originList valueForKey:TBKey_AfterParts];
        if (afterArr.count) {
            NSMutableDictionary *mAfterDict = [NSMutableDictionary dictionary];
            for (NSDictionary *infoItem in afterArr) {
                [self replaceWithOriginItem:infoItem container:mAfterDict];
            }
            [mtotalDict setValue:mAfterDict forKey:TBKey_AfterParts];
        }else {
            [mtotalDict setValue:[NSMutableDictionary dictionary] forKey:TBKey_AfterParts];
        }
    }
    [bookCache setValue:mtotalDict forKey:key];
}


- (void)replaceWithOriginItem:(NSDictionary *)originItem container:(NSMutableDictionary *)container {
    NSString *url = [originItem valueForKey:@"uri"];
    NSString *hasUrl = [NSString stringWithFormat:@"%lld",(unsigned long long)[url hash]];
    NSString *edtion = [originItem valueForKey:@"edition"];
    [container setValue:edtion forKey:hasUrl];
}

- (long long)getEdtion:(NSDictionary *)dict ForPath:(NSString *)path {
    if (dict && path) {
        NSDictionary *paths = [dict valueForKey:TBKey_Parts];
        NSString *edtion = [paths valueForKey:path];
        if (!edtion) {
            NSDictionary *beforePath = [dict valueForKey:TBKey_BeforeParts];
            edtion = [beforePath valueForKey:path];
        }
        if (!edtion) {
            NSDictionary *afterPath = [dict valueForKey:TBKey_AfterParts];
            edtion = [afterPath valueForKey:path];
        }
        return [edtion longLongValue];
    }
    return 0;
}


@end
